package com.edooteach.api.web.controller.shopping;

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.utils.JsonUtils;
import com.edoomath.entity.trade.PaymentRequest;
import com.edoomath.entity.trade.SalesOrder;
import com.edoomath.entity.user.User;
import com.edooteach.api.servcice.SalesOrderService;
import com.edooteach.api.servcice.UserService;
import com.edooteach.api.servcice.trading.PaymentRequestService;

/**
 * 
 * @author mohanlan
 *
 */
@Controller
@RequestMapping("/shopping")
public class ShoppingApiController {
    
    private static final Logger logger = LoggerFactory.getLogger(ShoppingApiController.class);
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private PaymentRequestService paymentRequestService;
    
    @Autowired
    private SalesOrderService salesOrderService;
    
    /**
     * 
     * @param orderId
     * @param unionid
     * @param request
     * @return
     */
    @RequestMapping(value = "/prepare", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public HttpResult onPay(@RequestParam("orderId") Long orderId,
                            @RequestParam("unionid") String unionid,
                            HttpServletRequest request) {
        
        HttpResult httpResult = new HttpResult();
        
        User user = userService.load(unionid);
        SalesOrder salesOrder = salesOrderService.load(orderId);
        
        String xRealIpHeader = request.getHeader("X-Real-IP"); // Only available after NGINX redirect
        String remoteIp = StringUtils.isBlank(xRealIpHeader) ? request.getRemoteAddr() : xRealIpHeader;
        logger.trace("#join() - Get remote IP address [{}].", remoteIp);
        
        Map<String, Object> payConfig = salesOrderService.prepay(salesOrder, user, remoteIp);
        return httpResult.success().data("payConfig", payConfig);
    }
    
    /**
     * 
     * @param body
     * @param request
     * @return
     */
    @RequestMapping(value = "/callback", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onPaid(@RequestBody String body,
                                           HttpServletRequest request) {
        
        Map<String, Object> params = JsonUtils.parse(body);
        
        logger.trace("#onPaid - Get rquest number [{}], order number [{}], amount [{}], pay time [{}], channel [{}].", 
                      params.get("requestNo"), params.get("orderNo"), params.get("transactionCode"), params.get("amount"), params.get("paymentTime"));
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            String requestCode = params.get("requestNo").toString();
            
            PaymentRequest paymentRequest = paymentRequestService.load(requestCode);
            
            // validate payment request
            if(paymentRequest == null) {
                throw new BusinessException("支付回调数据错误");
            }
            
            // validate payment request & order code
            String orderCode = params.get("orderNo").toString();
            if(!StringUtils.equalsIgnoreCase(orderCode, paymentRequest.getOrderCode())) {
                throw new BusinessException("支付回调数据异常");
            }
            
            // do pay order
            String payCode = params.get("transactionCode").toString();
            String payTime = params.get("paymentTime").toString();
            int amount = Integer.parseInt(params.get("amount").toString());
            
            SalesOrder salesOrder = salesOrderService.pay(paymentRequest, orderCode, payCode, payTime, amount);
            //smsSender.sendMessage("17621360181", "【陆老师小课堂】有新的用户[" + salesOrder.getUser().getNickname() + "]购买练习册["+salesOrder.getSku().getName()+"]。");
            
            httpResult.success().data("salesOrder", salesOrder).message("支付回调成功");
            
            // check order & update order, product things
            logger.trace("#onPaid() - Synchronizing order with result [{}] !!!!!!!!", httpResult.getMessage());
            
        } catch (BusinessException e) {
            httpResult.fail("500").message(e.getMessage());
        } catch (Exception e) {
            logger.error("#prepare - occurs error", e);
            httpResult.fail("500").message("请求支付数据失败");
        }
        
        return httpResult;
        
    }
}
